"""
创建贪吃蛇游戏窗口 640x480 px
绘制 绿色的蛇🐍，红色苹果🍎 20 px
让蛇运动起来
根据方向键修改朝向

判定碰撞
1. 碰到苹果，吃掉苹果，长身体
2. 碰到墙体，挂了，弹分数框
3. 碰到自己，挂了，弹分数框

基于PyQt5实现
"""


import random
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QKeyEvent, QPaintEvent
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

COLOR_BLACK  = QColor(0,0,0)
COLOR_RED    = QColor(255,0,0)
COLOR_GREEN  = QColor(0,255,0)
BLOCK_SIZE   = 20#块大小

SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480
BLOCK_SIZE = 20  # 块大小
SCREEN_W = SCREEN_WIDTH // BLOCK_SIZE  # 32
SCREEN_H = SCREEN_HEIGHT // BLOCK_SIZE # 24

DIR_UP   =(0,-1)
DIR_DOWN = (0,1)
DIR_LEFT = (-1,0)
DIR_RIGHT =(1,0)

# 创建窗口
class SnakeGame(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("贪吃蛇")
        self.resize(640, 480)
        # 创建画画板 QFrame
        self.frame = GameFrame(self)
        # 设置到当前窗口
        self.setCentralWidget(self.frame)


class GameFrame(QFrame):

    def __init__(self, parent: QWidget):
        super().__init__(parent)

        # 自动获取焦点
        self.setFocusPolicy(Qt.StrongFocus)
        # 初始化游戏
        self.init_game()

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_game)
        self.timer.start(200)

    def init_game(self):

        # 蛇   32,24
        self.snake = [[10, 5], [9, 5], [8, 5]]
        # food
        self.food = [20, 5]
        # 分数
        self.score = 0
        # 方向
        self.direction = DIR_RIGHT
        
    def generate_food(self):

        while True:
            # 随机生成食物
            food = [random.randint(0,31),random.randint(0,23)]
            if food  not in self.snake:
                break
        return food

    def update_game(self):
        head_x,head_y = self.snake[0]
        dir_x,dir_y = self.direction
        new_head = [head_x+dir_x,head_y+dir_y]
        self.snake.insert(0, new_head)
        head = self.snake[0]
        # 若蛇头吃到苹果长度+1，分数加一
        if head==self.food:
            self.food = self.generate_food()
            self.score +=1

        else:
            self.snake.pop()
        head_x,head_y = self.snake[0]

        # 判断蛇头是否撞墙
        if ((head_x>=SCREEN_W or head_x<0)or
            (head_y>=SCREEN_H or head_y<0)or
            self.snake[0] in self.snake[1:]
            ):
            print("游戏结束")
            QMessageBox.warning(self,"游戏结束",f"得分:{self.score}关闭窗口重启游戏")
            self.init_game()
        # 触发界面刷新
        self.update()

    def keyPressEvent(self, event: QKeyEvent) -> None:
        # print(event.key())
        if event.key() == Qt.Key_Up and self.direction != DIR_DOWN:
            self.direction = DIR_UP
        elif event.key() == Qt.Key_Down and self.direction != DIR_UP:
            self.direction = DIR_DOWN
        elif event.key() == Qt.Key_Left and self.direction != DIR_RIGHT:
            self.direction = DIR_LEFT
        elif event.key() == Qt.Key_Right and self.direction != DIR_LEFT:
            self.direction = DIR_RIGHT

    def paintEvent(self, event: QPaintEvent) -> None:
        painter = QPainter(self)
        # 绘制背景
        painter.setBrush(QBrush(COLOR_BLACK))
        painter.drawRect(self.rect())

        # 绘制食物
        painter.setBrush(QBrush(COLOR_RED))
        painter.drawRect(
            self.food[0] * BLOCK_SIZE, self.food[1] * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE
        )
        # 绘制蛇
        painter.setBrush(QBrush(COLOR_GREEN))
        for x, y in self.snake:
            painter.drawRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    game = SnakeGame()
    game.show()
    # 让主程序阻塞运行
    sys.exit(app.exec_())
